﻿using System.Collections.Concurrent;
using System.Linq;
using System.Text.RegularExpressions;

namespace CqCore.Messaging
{
    public class MessageTopicFilter
    {
        readonly Regex regex;
        readonly ConcurrentDictionary<string, bool> cache = new ConcurrentDictionary<string, bool>();

        public string Template { get; }

        public MessageTopicFilter(string topicTemplate)
        {
            this.Template = topicTemplate;

            var prevSegment = string.Empty;
            var segments = Template.Split('.').Select(segment =>
            {
                var result = string.Empty;

                if (!string.IsNullOrEmpty(prevSegment))
                {
                    result = prevSegment != "#" ? "\\.\\b" : "\\b";
                }
                if (segment == "#")
                {
                    result += "[\\s\\S]*";
                }
                else if (segment == "*")
                {
                    result += "[^.]+";
                }
                else
                {
                    result += segment;
                }

                prevSegment = segment;
                return result;
            });
            var pattern = $"^{string.Join("", segments)}$";

            regex = new Regex(pattern, RegexOptions.IgnoreCase);
        }

        public bool IsMatch(string topic)
        {
            return cache.GetOrAdd(topic, (key) => regex.IsMatch(key));
        }
    }
}
